﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using Estimate.Common.Memcached;
using Newtonsoft.Json;

namespace Estimate.Common.Estimate
{
    /// <summary>
    /// 程序执行状态类
    /// </summary>
   public  class ExecutionStatus
    {
       /// <summary>
       /// 任务号
       /// </summary>
       public string tid = "";
       public int current_step = 0;
       public int total_step = 0;
       public string message = "";
       public bool isFinished = false;
       private DateTime ExeStartTime;
       private DateTime LsetStepStartTime;
       private int StepNeedTime=0;

       /// <summary>
       /// 已经耗时
       /// </summary>
       public int time_out
       {
           get
           {
               if (ExeStartTime == null) return 0;

               return DateTime.Now.Subtract(ExeStartTime).Seconds;

           }
       }

       /// <summary>
       /// 预估总耗时
       /// </summary>
       public int need_time
       {
           get
           {
               if (current_step == 0)
                   return 0;
                 
               int left_step = total_step - current_step;
               float step_need = (float)time_out / (float)current_step;
               int need_seconds = time_out + (int)((float)left_step * (float)(step_need + StepNeedTime) / 2);
               //int need_minutes = need_seconds / 60;
               //need_seconds = need_seconds % 60;
               //string str= "程序执行估计需要" ;
               //if (need_minutes != 0)
               //    str += need_minutes.ToString() + "分,";
               //if (need_seconds != 0)
               //    str += need_seconds.ToString() + "秒";
               //return str;
               return need_seconds;
           }
       }

       /// <summary>
       /// 当前步数
       /// </summary>
        [JsonIgnore]
        public int CurrentStep
        {
            get { return current_step; }
            set
            {
                current_step = value;
                SetStatusToCache(true);

                if (LsetStepStartTime == null)
                    StepNeedTime = 0;
                else
                {
                    StepNeedTime = DateTime.Now.Subtract(LsetStepStartTime).Seconds;
                    LsetStepStartTime = DateTime.Now;
                }
            }
        }

       /// <summary>
       /// 任务执行总步数
       /// </summary>
       [JsonIgnore]
       public int TotalSteps
       {
           get { return total_step; }
           set { total_step = value; }
       }


        [JsonIgnore]
        private XmlDocument doc = new XmlDocument();


        [JsonIgnore]
        private static MemcachedClient CacheClient;

        public ExecutionStatus()
        { }

       public ExecutionStatus(string Tid)
       {
           tid = Tid;
           ExeStartTime = DateTime.Now;

           doc.LoadXml("<Status></Status>");

           if (CacheClient == null)
           {
               if (!MemcachedClient.Exists("localhost"))
                   MemcachedClient.Setup("localhost", new string[] { "127.0.0.1:11211" });
               CacheClient = MemcachedClient.GetInstance("localhost");
               CacheClient.SendReceiveTimeout = 5000;
               CacheClient.ConnectTimeout = 5000;
               CacheClient.MinPoolSize = 1;
               CacheClient.MaxPoolSize = 10;
           }

       }

       public void SetMessage(bool finished, string nodeName, string message)
       {
           isFinished = finished;
           SetMessage(nodeName, message);
       }
       public void SetMessage(string nodeName, string msg)
       {
           try
           {
               XmlNode xn = doc.LastChild;
               XmlElement xe = doc.CreateElement(nodeName);
               xe.SetAttribute("message", msg);
               xn.AppendChild(xe);

               message = AssemblyMessage(doc.SelectSingleNode("Status").ChildNodes);
               message = message.Remove(message.LastIndexOf('/'), 1);
               SetStatusToCache(true);
           }
           catch(Exception ex)
           {
               this.message = ex.Message;
               SetStatusToCache(false);
           }
       }

       public void DeleteMessage(string nodeName)
       {
           XmlNode xn = doc.SelectSingleNode("//" + nodeName);
           if (xn != null)
           {
               xn.RemoveAll();
               xn.ParentNode.RemoveChild(xn);
           }
          
       }

       private string AssemblyMessage(XmlNodeList XmlNodes)
       {
           string msg = "";
           foreach (XmlNode xn in XmlNodes)
           {
               msg += xn.Attributes["message"].Value + "/";
               if (xn.ChildNodes != null)
                   msg += AssemblyMessage(xn.ChildNodes);
           }
           return msg;
       }

       private void SetStatusToCache(bool success)
       {
           ExecutionStatusResult Result = new ExecutionStatusResult();
           Result.success = success.ToString();
           Result.result.Add("data", this);
           if (CacheClient.Get(tid) != null)
               CacheClient.Replace(tid, JsonConvert.SerializeObject(Result));
           else
               CacheClient.Set(tid, JsonConvert.SerializeObject(Result));
       }

       public string GetStatusFromCache(string Tid)
       {
           if (Tid == "")
           {
               ExecutionStatusResult result = new ExecutionStatusResult();
               result.success = false.ToString();
               result.msg = "执行状态任务号为空";
               return JsonConvert.SerializeObject(result);
           }

           if(CacheClient==null)
           {
               ExecutionStatusResult result = new ExecutionStatusResult();
               result.success = false.ToString();
               result.msg = "缓存客户端未初始化";
               return JsonConvert.SerializeObject(result);
           }

           object ob = CacheClient.Get(Tid);
           if (ob == null)
           {
               ExecutionStatusResult result = new ExecutionStatusResult();
               result.success = false.ToString();
               result.msg = "缓存中不存在任务号为" + Tid + "执行状态";
               return JsonConvert.SerializeObject(result);
           }

           return ob.ToString();
       }
       
       public bool DeleteStatusFromCache(string Tid)
       {
           return CacheClient.Delete(Tid);
       }

       
    }

   public class ExecutionStatusResult
   {
       public string success = true.ToString();
       public string msg = "";
       public Dictionary<string, ExecutionStatus> result = new Dictionary<string,ExecutionStatus>();

      
   }

}
